package com.dcyao.musicserve.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.dcyao.musicserve.common.R;
import com.dcyao.musicserve.domain.ListStaff;
import com.dcyao.musicserve.domain.Staff;
import com.dcyao.musicserve.domain.dto.StaffCollectDTO;
import com.dcyao.musicserve.domain.dto.StaffDTO;
import com.dcyao.musicserve.mapper.ListStaffMapper;
import com.dcyao.musicserve.mapper.StaffMapper;
import com.dcyao.musicserve.service.StaffService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;

/**
 * @ClassName StaffController
 * @Description:乐谱
 * @Version:1.0
 */
@RestController
@RequestMapping("/staff")
public class StaffController {
    @Value("${files.upload.path}")
    private String fileUploadPath;
    @Autowired
    private StaffService staffService;
    @Autowired
    private StaffMapper staffMapper;
    @Autowired
    private ListStaffMapper listStaffMapper;

    @GetMapping("/selectUpdateStaffByConsumerId")
    public R selectUpdateStaffByConsumerId(@RequestParam(defaultValue = "1") Integer pageNum,
                                           @RequestParam(defaultValue = "10") Integer pageSize,
                                           @RequestParam(defaultValue = "") Integer consumerId) {
        Page<StaffDTO> page = staffService.selectUpdateStaffByConsumerId(new Page<>(pageNum, pageSize),consumerId);
        return R.success("查询成功", page);
    }

    /**
     * 根据乐谱集id查找乐谱
     *
     * @return
     */
    @GetMapping("/staffPage")
    public R allUser(@RequestParam(defaultValue = "1") Integer pageNum,
                     @RequestParam(defaultValue = "10") Integer pageSize,
                     @RequestParam(defaultValue = "") Integer staffListId,
                     @RequestParam(defaultValue = "") String name) {
        Page<StaffDTO> page = staffService.selectStaff(new Page<>(pageNum, pageSize), staffListId, name);
        return R.success("查询成功", page);
    }

    /**
     * 根据乐谱集id查找乐谱不分页
     *
     * @return
     */
    @GetMapping("/staffs")
    public R allStaff(@RequestParam(defaultValue = "") Integer staffListId) {
        return staffService.selectStaffs(staffListId);
    }

    /**
     * 分页查询全部用户
     *
     * @return
     */
    @GetMapping("/page")
    public R findUserAll(@RequestParam(defaultValue = "1") Integer pageNum,
                         @RequestParam(defaultValue = "10") Integer pageSize,
                         @RequestParam(defaultValue = "") String name, @RequestParam(defaultValue = "") Integer consumerId) {
        return staffService.findPage(pageNum, pageSize, name, consumerId);
    }

    /**
     * 编辑
     *
     * @param updateRequest
     * @return
     */
    @PostMapping("/update")
    public R updateStaffMsg(@RequestBody StaffDTO updateRequest) {
        return staffService.updateStaff(updateRequest);
    }

    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    @GetMapping("/delete")
    public R deleteStaff(@RequestParam int id) {
        return staffService.deleteStaff(id);
    }


    /**
     * 批量删除
     *
     * @param ids
     * @return
     */
    @PostMapping("/delBatch")
    public R deleteBathIds(@RequestBody List<Integer> ids) {
        return staffService.deleteBathIds(ids);
    }

    /**
     * 根据用户id查找歌曲
     *
     * @param consumerId
     * @return
     */
    @GetMapping("/detail")
    public R selectByConsumerIds(@RequestParam int consumerId) {
        return staffService.selectByConsumerIds(consumerId);
    }

    /**
     * 更新封面
     *
     * @param file
     * @param id
     * @return
     * @throws IOException
     */
    @PostMapping("/upload")
    public String upload(@RequestParam MultipartFile file, @RequestParam Integer id) throws IOException {
        //获取文件原名
        String originalFilename = file.getOriginalFilename();
        //获取文件类型，即后缀名
        String type = FileUtil.extName(originalFilename);
        //先存储到磁盘
        File uploadParentFile = new File(fileUploadPath);
        //判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
        if (!uploadParentFile.exists()) {
            uploadParentFile.mkdirs();
        }
        //定义一个文件唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        //文件标识位
        String fileUUID = uuid + StrUtil.DOT + type;
        File uploadFile = new File(fileUploadPath + fileUUID);
        String url;
        //上传文件到磁盘
        file.transferTo(uploadFile);
        //获取文件的md5
        String md5 = SecureUtil.md5(uploadFile);
        //从数据库查询是否存在相同的记录
        Staff dbFiles = getFileByMd5(md5);
        if (dbFiles != null) {
            url = dbFiles.getPicture();
            //由于文件已存在，所以删除刚才上传的重复文件
            uploadFile.delete();
        } else {
            //数据若不存在重复文件，则不删除刚才上传的文件
            url = "http://localhost:8888/staff/" + fileUUID;
        }
        //存储数据库
        Staff sysFile = new Staff();
        sysFile.setId(id);
        sysFile.setPicture(url);
        staffService.saveOrUpdate(sysFile);
        return url;
    }

    /**
     * 用户上传乐谱
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/uploads")
    public R uploads(@RequestParam MultipartFile file, @RequestParam MultipartFile picture,
                     @RequestParam String name, @RequestParam String introduction,
                     @RequestParam Integer consumerId, @RequestParam String staffListId) throws IOException {
        //获取文件原名
        String originalFilename = file.getOriginalFilename();
        String originalPicturename = picture.getOriginalFilename();
        //获取文件类型，即后缀名
        String type = FileUtil.extName(originalFilename);
        String pictureType = FileUtil.extName(originalPicturename);
        //先存储到磁盘
        File uploadParentFile = new File(fileUploadPath);
        //判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
        if (!uploadParentFile.exists()) {
            uploadParentFile.mkdirs();
        }
        //定义一个文件唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        //文件标识位
        String fileUUID = uuid + StrUtil.DOT + type;
        String pictureUUID = uuid + StrUtil.DOT + pictureType;
        File uploadFile = new File(fileUploadPath + fileUUID);
        File uploadPicture = new File(fileUploadPath + pictureUUID);
        String url;
        String pictureUrl;
        //上传文件到磁盘
        file.transferTo(uploadFile);
        picture.transferTo(uploadPicture);
        //获取文件的md5
        String md5 = SecureUtil.md5(uploadFile);
        String md5Picture = SecureUtil.md5(uploadPicture);
        //从数据库查询是否存在相同的记录
        Staff dbFiles = getFileByMd5(md5);
        Staff dbPicture = getFileByMd5(md5Picture);
        if (dbFiles != null) {
            url = dbFiles.getPicture();
            //由于文件已存在，所以删除刚才上传的重复文件
            uploadFile.delete();
        } else {
            //数据若不存在重复文件，则不删除刚才上传的文件
            url = "http://localhost:8888/staff/" + fileUUID;
        }
        if (dbPicture != null) {
            pictureUrl = dbFiles.getPicture();
            //由于文件已存在，所以删除刚才上传的重复文件
            uploadFile.delete();
        } else {
            //数据若不存在重复文件，则不删除刚才上传的文件
            pictureUrl = "http://localhost:8888/staff/" + pictureUUID;
        }

        //存储数据库
        Staff sysFile = new Staff();
        sysFile.setName(name);
        sysFile.setConsumerId(consumerId);
        sysFile.setIntroduction(introduction);
        sysFile.setViewCounts(0);
        sysFile.setType(2);
        sysFile.setPicture(pictureUrl);
        sysFile.setFile(url);
        staffService.saveOrUpdate(sysFile);
        ListStaff listStaff = new ListStaff();
        listStaff.setStaffListId(Integer.parseInt(staffListId));
        listStaff.setStaffId(sysFile.getId());
        listStaffMapper.insert(listStaff);
        return R.success("上传成功");
    }

    /**
     * 用户重新上传
     *
     * @param file
     * @return
     * @throws IOException
     */
    @PostMapping("/againUploads")
    public R againUploads(@RequestParam MultipartFile file, @RequestParam MultipartFile picture,
                          @RequestParam Integer id, @RequestParam String name, @RequestParam String introduction,
                          @RequestParam Integer consumerId,@RequestParam Integer staffListId,
                          @RequestParam Integer listStaffId) throws IOException {
        //获取文件原名
        String originalFilename = file.getOriginalFilename();
        String originalPicturename = picture.getOriginalFilename();
        //获取文件类型，即后缀名
        String type = FileUtil.extName(originalFilename);
        String pictureType = FileUtil.extName(originalPicturename);
        //先存储到磁盘
        File uploadParentFile = new File(fileUploadPath);
        //判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
        if (!uploadParentFile.exists()) {
            uploadParentFile.mkdirs();
        }
        //定义一个文件唯一的标识码
        String uuid = IdUtil.fastSimpleUUID();
        //文件标识位
        String fileUUID = uuid + StrUtil.DOT + type;
        String pictureUUID = uuid + StrUtil.DOT + pictureType;
        File uploadFile = new File(fileUploadPath + fileUUID);
        File uploadPicture = new File(fileUploadPath + pictureUUID);
        String url;
        String pictureUrl;
        //上传文件到磁盘
        file.transferTo(uploadFile);
        picture.transferTo(uploadPicture);
        //获取文件的md5
        String md5 = SecureUtil.md5(uploadFile);
        String md5Picture = SecureUtil.md5(uploadPicture);
        //从数据库查询是否存在相同的记录
        Staff dbFiles = getFileByMd5(md5);
        Staff dbPicture = getFileByMd5(md5Picture);
        if (dbFiles != null) {
            url = dbFiles.getPicture();
            //由于文件已存在，所以删除刚才上传的重复文件
            uploadFile.delete();
        } else {
            //数据若不存在重复文件，则不删除刚才上传的文件
            url = "http://localhost:8888/staff/" + fileUUID;
        }
        if (dbPicture != null) {
            pictureUrl = dbFiles.getPicture();
            //由于文件已存在，所以删除刚才上传的重复文件
            uploadFile.delete();
        } else {
            //数据若不存在重复文件，则不删除刚才上传的文件
            pictureUrl = "http://localhost:8888/staff/" + pictureUUID;
        }
        //存储数据库
        Staff sysFile = new Staff();
        sysFile.setId(id);
        sysFile.setName(name);
        sysFile.setConsumerId(consumerId);
        sysFile.setIntroduction(introduction);
        sysFile.setViewCounts(0);
        sysFile.setType(2);
        sysFile.setPicture(pictureUrl);
        sysFile.setFile(url);
        staffService.updateById(sysFile);
        ListStaff listStaff = new ListStaff();
        listStaff.setId(listStaffId);
        listStaff.setStaffId(sysFile.getId());
        listStaff.setStaffListId(staffListId);
        listStaffMapper.updateById(listStaff);
        return R.success("上传成功");
    }

    /**
     * 通过文件的md5查询文件
     *
     * @param md5
     * @return
     */
    private Staff getFileByMd5(String md5) {
        //查询文件的md5是否存在
        QueryWrapper<Staff> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5", md5);
        List<Staff> fileList = staffMapper.selectList(queryWrapper);
        return fileList.size() == 0 ? null : fileList.get(0);
    }

    /**
     * 根据乐谱id查找乐谱对象
     *
     * @param staffId
     * @return
     */
    @GetMapping("/selectByStaffIds")
    public R selectByStaffIds(@RequestParam int staffId) {
        return staffService.selectByStaffIds(staffId);
    }

    /**
     * 查询用户、乐谱集、乐谱总数
     *
     * @return
     */
    @GetMapping("/findStaffs")
    public List<Integer> findStaffs() {
        return staffService.staffCount();
    }

    /**
     * 模糊查询乐谱名
     *
     * @param name
     * @return
     */
    @GetMapping("/likeStaffName")
    public R likeStaffName(@RequestParam String name) {
        return staffService.likeStaffName(name);
    }

    /**
     * 最新乐谱
     *
     * @return
     */
    @PostMapping("/new")
    public R newArticles() {
        return staffService.newStaffs();
    }

    /**
     * 最热乐谱
     *
     * @return
     */
    @PostMapping("/hot")
    public R hotArticles() {
        return staffService.hotStaffs();
    }

    /**
     * 根据用户id查询该用户收藏的乐谱详情
     *
     * @param consumerId
     * @return
     */
    @GetMapping("/likeStaff")
    public R likeStaff(@RequestParam Integer consumerId) {
        return staffService.likeStaff(consumerId);
    }

    /**
     * 根据用户id查询该用户收藏的乐谱详情分页
     *
     * @param consumerId
     * @return
     */
    @GetMapping("/likeStaffPage")
    public R likeStaffPage(@RequestParam(defaultValue = "1") Integer pageNum,
                           @RequestParam(defaultValue = "10") Integer pageSize,
                           @RequestParam(defaultValue = "") Integer consumerId) {
        Page<StaffCollectDTO> page = staffService.likeStaffPage(new Page<>(pageNum, pageSize), consumerId);
        return R.success("查询成功", page);
    }

    /**
     * 管理员审批
     *
     * @return
     */
    @GetMapping("/updateStaffType")
    public R updateStaffType(@RequestParam Integer staffId, @RequestParam Integer type) {
        return staffService.changeStaffType(staffId, type);
    }

    /**
     * 下载数量加一
     *
     * @param staffId
     * @return
     */
    @GetMapping("/addViewCount")
    public R addViewCount(@RequestParam Integer staffId) {
        return staffService.addViewCount(staffId);
    }

    /**
     * 文件下载：下载路径 http://localhost:8888/admin/{fileUUID}
     *
     * @param fileUUID
     * @param response
     */
    @GetMapping("/{fileUUID}")
    public void download(@PathVariable String fileUUID, HttpServletResponse response) throws IOException {
        //根据文件的唯一标识码获取文件
        File uploadFile = new File(fileUploadPath + fileUUID);
        //设置输出流的格式
        ServletOutputStream os = response.getOutputStream();
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileUUID, "UTF-8"));
        response.setContentType("application/octet-stream");
        //读取文件的字节流
        os.write(FileUtil.readBytes(uploadFile));
        os.flush();
        os.close();
    }


    /**
     * 导出数据
     *
     * @param response
     */
    @GetMapping("/export")
    public void export(HttpServletResponse response) throws IOException {
        //从数据库查询出所以的数据
        List<Staff> list = staffService.list();
        //在内存操纵，写出到浏览器
        ExcelWriter writer = ExcelUtil.getWriter(true);
        //一次性写出list内的对象到excel，使用默认样式，强制输出标题
        writer.write(list, true);
        //设置浏览器响应的格式
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
        String fileName = URLEncoder.encode("用户上传乐谱信息", "UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx");
        ServletOutputStream out = response.getOutputStream();
        writer.flush(out, true);
        out.close();
        writer.close();
    }


}


